<?php

/***  Documentation

    Analytics Class Unit Test
    
    Revision: $Rev$
    Last Update: $Date: 2009-05-21 04:48:45 +0000 (Thu, 21 May 2009) $
    Author: Tom at klenwell@gmail.com
  
NOTES

______________________________________________________________________________*/

$dn1 = dirname;
$ds = DIRECTORY_SEPARATOR;
$libdir = $dn1($dn1($dn1(__FILE__))) . $ds . 'lib' . $ds;
$grqdir = $dn1($libdir) . $ds . 'greqo' . $ds;
require_once($libdir . "simpletest{$ds}unit_tester.php");
require_once($grqdir . "analytics.class.php");

class AnalyticsTestCase extends UnitTestCase {
    
    var $debug = 0;
    var $is_set_up_once = 0;
    
    var $test_markup = '';
    var $traffic_report_xml = '';

    
    function setUp() 
    {
        $this->setUpOnce();
        $this->test_markup = <<<XHTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html> <head>
<title>Analytics Settings - Google Analytics</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!-- CUT -->
</head>

<body><div id="container" class="admin_container">  <span class=""> <div id="header"> <div id="main_header"> <p id="logo"><a href="/analytics/settings/home"></a></p> <table id="global_header_nav"><tr> <td><span id="f_email" class="email_address">greqophp@gmail.com</span></td> <td>|</td>  <td><a href="/analytics/settings/my_account?scid=10000">Settings</a></td> <td>|</td> <td>
<a href="https://www.google.com/accounts/ManageAccount">My Account</a></td> <td>|</td>  <td><a href="http://www.google.com/support/googleanalytics/?hl=en_US" target="GoogleHelp">Help</a></td> <td>|</td>  <td><a href="https://www.google.com/accounts/Logout?hl=en-US&amp;continue=https://www.google.com/analytics/settings/" id="logout">Sign Out</a></td>  </tr></table> </div>
<div id="subheader"> <div><div><div>
<div id="account_profile_nav">
<form id="account_profile_selector" action="/analytics/reporting/" method="get"> <p id="profile_nav">  <input type="hidden" name="reset" value="1"> <a class="settings" id="settings_link" href="/analytics/settings/home?scid=12345">Analytics Settings</a>  <a class="view_report" href="/analytics/reporting/?id=300"> View Reports: </a>
<select name="id" id="profile" onchange="this.form.submit()">
<option value="0">Click to select Website Profile</option>
<option value="100000">code.google.com/p/klenwell/</option>
<option value="100001">code.google.com/p/greqo/</option>
<option value="100003">klenwell.com</option>
</select>
</p> </form> <form id="account_selector" name="account_selector" action="/analytics/settings/home" method="get"> <p id="account_nav">  <label for="account"> My Analytics Accounts: </label> <script type="text/javascript">function submitAccountSelectorForm(id) { if (id == 0) { location.href = "/analytics/provision/"; } else { document.account_selector.submit(); } }</script>
<script type="text/javascript">var adminLinkBuilder = new analytics.AdminLinkBuilder( "100000", "100001");</script>
<select name="scid" id="account" onchange="submitAccountSelectorForm(this.value)">
<option selected value="100000">John</option>
<option value="100001">Paul</option>
<option value="100002">George</option>
<option value="100003">Ringo</option>
<optgroup style="font-weight: normal" label="-------------------------------"></optgroup>
<option value="0">Create New Account...</option>
</select>
</p> </form> </div>  </div></div></div> </div> </div>
<div id="content">
<!-- CUT -->
</div> </body> </html>
XHTML;

        $this->traffic_report_xml = <<<HXML
<?xml version="1.0" ?><AnalyticsReport><Report name="Visitors Overview"><Title id="Title"><CompareStateHelp>Compare all data against the previous date range.</CompareStateHelp><Detail></Detail><ShowDateControl>true</ShowDateControl><PrimaryDateRange>April 28, 2009 - April 28, 2009</PrimaryDateRange><Compare>true</Compare><Sampled>false</Sampled><CompareStateMsg>April 27, 2009 - April 27, 2009</CompareStateMsg><CompareDateRange>April 27, 2009 - April 27, 2009</CompareDateRange><Name>Visitors Overview</Name><CompareMsg>Comparing to:</CompareMsg><ProfileName>Phosphorus and Lime (blog)</ProfileName><ShowCompare>true</ShowCompare><DetailSeparator> | </DetailSeparator></Title><Narrative id="NarrativeTitle"><Line><LineType>NORMAL</LineType><Content>29 people visited this site</Content></Line><Type>NORMAL</Type><Compare>true</Compare></Narrative><ItemSummary id="VisitsSummary"><Item><SummaryValue>31</SummaryValue></Item><Active>true</Active><Message>Visits</Message><InverseCompare>false</InverseCompare><Delta>-20.51%</Delta><SubMessage>Previous: 39</SubMessage><Compare>true</Compare></ItemSummary><ItemSummary id="VisitorsSummary"><Item><SummaryValue>29</SummaryValue></Item><Active>true</Active><Message>Absolute Unique Visitors</Message><InverseCompare>false</InverseCompare><Delta>-17.14%</Delta><SubMessage>Previous: 35</SubMessage><Compare>true</Compare></ItemSummary><ItemSummary id="PageviewsSummary"><Item><SummaryValue>39</SummaryValue></Item><Active>true</Active><Message>Pageviews</Message><InverseCompare>false</InverseCompare><Delta>-7.14%</Delta><SubMessage>Previous: 42</SubMessage><Compare>true</Compare></ItemSummary><ItemSummary id="AvgPageviewsSummary"><Item><SummaryValue>1.26</SummaryValue></Item><Active>true</Active><Message>Average Pageviews</Message><InverseCompare>false</InverseCompare><Delta>16.82%</Delta><SubMessage>Previous: 1.08</SubMessage><Compare>true</Compare></ItemSummary><ItemSummary id="TimeOnSiteSummary"><Item><SummaryValue>00:00:47</SummaryValue></Item><Active>true</Active><Message>Time on Site</Message><InverseCompare>false</InverseCompare><Delta>24.95%</Delta><SubMessage>Previous: 00:00:38</SubMessage><Compare>true</Compare></ItemSummary><ItemSummary id="BounceRateSummary"><Item><SummaryValue>87.10%</SummaryValue></Item><Active>true</Active><Message>Bounce Rate</Message><InverseCompare>true</InverseCompare><Delta>-5.65%</Delta><SubMessage>Previous: 92.31%</SubMessage><Compare>true</Compare></ItemSummary><ItemSummary id="NewVisitsSummary"><Item><SummaryValue>90.32%</SummaryValue></Item><Active>true</Active><Message>New Visits</Message><LinkParams>view=1</LinkParams><InverseCompare>false</InverseCompare><Delta>6.74%</Delta><SubMessage>Previous: 84.62%</SubMessage><Compare>true</Compare></ItemSummary><Narrative id="Narrative"><Line><LineType>NORMAL</LineType><Content>Technical Profile</Content></Line><Type>NORMAL</Type><Compare>true</Compare></Narrative></Report></AnalyticsReport>
HXML;

        $this->sources_report_csv = <<<XCSV
# ----------------------------------------
Phosphorus and Lime (blog)
All Traffic Sources,
"April 28, 2009","April 28, 2009"
# ----------------------------------------

# ----------------------------------------
# Graph
# ----------------------------------------
Day,Visits
"Tuesday, April 28, 2009",31

# ----------------------------------------
# Table
# ----------------------------------------
Source/Medium,Visits,Pages/Visit,Avg. Time on Site,% New Visits,Bounce Rate,Visits,Goal1 Conversion Rate,Goal Conversion Rate,Per Visit Goal Value
google / organic,24,1.2916666666666667,38.583333333333336,0.9166666666666666,0.875,24,0.0,0.0,0.0
(direct) / (none),4,1.25,132.25,0.75,0.75,4,0.0,0.0,0.0
forums.digitalpoint.com / referral,1,1.0,0.0,1.0,1.0,1,0.0,0.0,0.0
linux.derkeiler.com / referral,1,1.0,0.0,1.0,1.0,1,0.0,0.0,0.0
phwinfo.com / referral,1,1.0,0.0,1.0,1.0,1,0.0,0.0,0.0
# --------------------------------------------------------------------------------
XCSV;

        $this->keywords_report_csv = <<<XCSV
# ----------------------------------------
Phosphorus and Lime (blog)
Keywords,
"April 28, 2009","April 28, 2009"
# ----------------------------------------

# ----------------------------------------
# Graph
# ----------------------------------------
Day,Visits
"Tuesday, April 28, 2009",24

# ----------------------------------------
# Table
# ----------------------------------------
Keyword,Visits,Pages/Visit,Avg. Time on Site,% New Visits,Bounce Rate,Visits,Goal1 Conversion Rate,Goal Conversion Rate,Per Visit Goal Value
php cronjob make mysql dump?,2,1.0,0.0,0.5,1.0,2,0.0,0.0,0.0
ubuntu email from command line,2,1.5,39.5,0.5,0.5,2,0.0,0.0,0.0
_server['http_x_bluecoat_via'] php,1,1.0,0.0,1.0,1.0,1,0.0,0.0,0.0
1 and 1 auto renew,1,6.0,759.0,1.0,0.0,1,0.0,0.0,0.0
alphanum php,1,1.0,0.0,1.0,1.0,1,0.0,0.0,0.0
att site for repairing your connection,1,1.0,0.0,1.0,1.0,1,0.0,0.0,0.0
difference between branch ang tags,1,1.0,0.0,1.0,1.0,1,0.0,0.0,0.0
firefox grabber,1,1.0,0.0,1.0,1.0,1,0.0,0.0,0.0
levelselectedstyles in sharepoint,1,1.0,0.0,1.0,1.0,1,0.0,0.0,0.0
line wrap css,1,1.0,0.0,1.0,1.0,1,0.0,0.0,0.0
# --------------------------------------------------------------------------------
XCSV;

        $this->content_report_csv = <<<XCSV
# ----------------------------------------
Phosphorus and Lime (blog)
Top Content,
"April 28, 2009","April 28, 2009"
# ----------------------------------------

# ----------------------------------------
# Graph
# ----------------------------------------
Day,Pageviews
"Tuesday, April 28, 2009",39

# ----------------------------------------
# Table
# ----------------------------------------
Page,Pageviews,Unique Pageviews,Avg. Time on Page,Bounce Rate,% Exit,$ Index
/2008/05/ubuntu-command-line-email.html,8,7,79.0,0.8571428571428571,0.875,0.0
/2007/06/how-to-cancel-domain-auto-renewal-for.html,6,1,152.0,0.0,0.16666666666666666,0.0
/2005/12/php-sort-array-by-one-field-in-array.html,4,3,88.0,0.6666666666666666,0.75,0.0
/2006/12/phpmysql-mysqldump-automated-backup.html,4,4,0.0,1.0,1.0,0.0
/2005/11/php-fuzzy-search-functions.html,2,1,529.0,0.0,0.5,0.0
/2007/08/php-get-base-domain.html,2,2,0.0,1.0,1.0,0.0
/2008/11/troubleshooting-your-at-dsl-connection.html,2,2,0.0,1.0,1.0,0.0
/2005/10/css-latest-myspace-profile-stylesheet.html,1,1,0.0,1.0,1.0,0.0
/2005/11/css-line-wrap.html,1,1,0.0,1.0,1.0,0.0
/2005/11/php-parent-directory.html,1,1,0.0,1.0,1.0,0.0
# --------------------------------------------------------------------------------
XCSV;
    }
    
    function tearDown() 
    {
    }
    
    function setUpOnce()
    {
        if ( $this->is_set_up_once ) return;      
        
        // set up
        $utime = microtime();
        $this->start_timer = substr($utime,0,9) + substr($utime,-10);
        $this->is_set_up_once = 1;
        
        $this->Analytics = new GreqoAnalytics($start_session=0);
    }
    
    

    /* TEST METHODS */  
    function testTest() { $this->assertTrue(1); }
    function testInstance()
    {
        $this->assertTrue(is_a($this->Analytics, 'GreqoAnalytics'));
    }
    
    function testAnalyticsError()
    {
        $this->expectError();
        $this->Analytics->err('unit test');
    }
    
    function testAccountParser()
    {
        $AccountList = $this->Analytics->_parse_account_list($this->test_markup);
        #$this->pr($AccountList);
        $this->assertEqual($AccountList['John'], '100000');
        $this->assertEqual(count($AccountList), 4);
    }
    
    function testProfileParser()
    {
        $ProfileList = $this->Analytics->_parse_profile_list($this->test_markup);
        #$this->pr($ProfileList);
        $this->assertEqual($ProfileList['klenwell.com'], '100003');
        $this->assertEqual(count($ProfileList), 3);
    }
    
    function testYmdToTime()
    {
        $Ymd = '20080101';
        $expect = '2008-01-01';
        $this->assertEqual( $expect, date('Y-m-d', strtotime($Ymd)) );
        
        $Ymd = '20080101';
        $expect = '2007-12-31';
        $this->assertEqual( $expect, date('Y-m-d', strtotime($Ymd) - 86400) );
    }
    
    function testGetReportUrl()
    {
        $sid = 100;
        $report = 'traffic';
        $date = '2009-01-01';
        $expect = 'https://www.google.com/analytics/reporting/export?rpt=VisitorsOverviewReport&id=100&fmt=2&pdr=20090101-20090101&cmp=date_range&cdr=20081231-20081231&trows=10';
        $url = $this->Analytics->_build_report_url($sid, $report, $date);
        $this->assertEqual( $expect, $url );
    }
    
    function testCacheId()
    {
        $url = 'https://www.google.com/analytics/reporting/export?rpt=VisitorsOverviewReport&id=100&fmt=2&pdr=20090101-20090101&cmp=date_range&cdr=20081231-20081231&trows=10';
        $expect = 'cache-dcc995bc2155c25a558e7a3e884e8562';
        $cache_id = $this->Analytics->_get_cache_id($url);
        $this->assertEqual( $expect, $cache_id );
    }
    
    function testParseTrafficReportXml()
    {
        $Report = $this->Analytics->_parse_traffic_xml($this->traffic_report_xml);
        $this->assertEqual($Report['ProfileName'], 'Phosphorus and Lime (blog)');
        $this->assertEqual($Report['DateRange'], '20090428-20090428');
        $this->assertEqual($Report['VisitsSummary']['value'], '31');
        $this->assertEqual($Report['VisitorsSummary']['previous'], '35');
        $this->assertEqual($Report['PageviewsSummary']['change'], '-7.14%');
        #$this->pr($Report);
    }
    
    function testParseSourceReportCsv()
    {
        $Report = $this->Analytics->_parse_ga_csv($this->sources_report_csv);
        $this->assertEqual($Report['ProfileName'], 'Phosphorus and Lime (blog)');
        $this->assertEqual($Report['ReportName'], 'All Traffic Sources');
        $this->assertEqual($Report['DateRange'], '20090428-20090428');
        $this->assertEqual($Report['Table']['Header'][3], 'Avg. Time on Site');
        $this->assertEqual($Report['Table']['Rows'][0]['Source/Medium'], 'google / organic');
        $this->assertEqual($Report['Table']['Rows'][0]['Avg. Time on Site'], '38.583333333333336');
        #$this->pr($Report);
    }
    
    function testBuildSummaryReport()
    {
        $Report['traffic'] = $this->Analytics->_parse_traffic_xml($this->traffic_report_xml);
        $Report['sources'] = $this->Analytics->_parse_ga_csv($this->sources_report_csv);
        $Report['keywords'] = $this->Analytics->_parse_ga_csv($this->keywords_report_csv);
        $Report['content'] = $this->Analytics->_parse_ga_csv($this->content_report_csv);
        $SummaryReport = $this->Analytics->build_summary_report($Report);
        
        // test
        $ReportParts = explode('# ----------------------------------------', $SummaryReport);
        $ReportLines0 = explode("\n", $ReportParts[0]);
        $ReportLines1 = explode("\n", $ReportParts[1]);
        $ReportLines2 = explode("\n", $ReportParts[2]);
        $ReportLines3 = explode("\n", $ReportParts[3]);
        $ReportLines4 = explode("\n", $ReportParts[4]);
        $this->assertEqual($ReportLines0[0],'Greqo Analytics Summary for Phosphorus and Lime (blog)');
        $this->assertEqual($ReportLines1[1],'# TRAFFIC');
        $this->assertEqual($ReportLines2[1],'# SOURCES');
        $this->assertEqual($ReportLines3[1],'# KEYWORDS');
        $this->assertEqual($ReportLines4[1],'# CONTENT');

        #$this->pr($Report);
        #$this->pr($ReportParts);
        #$this->pr($this->Analytics->build_summary_report($Report));
    }
    



    /* HELPER METHODS */
    function get_script_time()
    {
        $utime = microtime();
        return number_format((substr($utime,0,9) + substr($utime,-10)) - $this->start_timer, 4);
    }

    function kill($html, $message='dying')
    {
        $this->print_d(htmlspecialchars($html), '#600');
        print $html;
        die($message);
    }
    
    function echo_d($message, $color='#ccc')
    {
        $_D = debug_backtrace();
        $f = basename($_D[0]['file']);
        $l = $_D[0]['line'];
        $loc = "{$f}:{$l}";
        $out = "<div style='line-height:1.5em; font-family:monospace; color:$color;'>$message <span style='color:#666;'>[$loc]</span></div>";
        $this->_DBG[] = "$loc -> " . strip_tags($message);
        echo $out;
        return;
    }
    
    function print_d($message, $color='#c33')
    {
        if ( $this->debug ) $this->echo_d($message, $color);
        return;
    }
    
    function print_r($Mixed)
    {
        $return = htmlspecialchars(print_r($Mixed, 1));
        $return = "<pre>$return</pre>";
        return $return;
    }
    
    function pr($Mixed, $header='')
    {
        if ( !empty($header) ) $header = "<b>$header</b>";
        $return = htmlspecialchars(print_r($Mixed, 1));
        $return = "<pre style='border:1px solid #ccc; background:#f3f3f3; padding:4px;'>$header\n\n$return</pre>";
        $this->echo_d($return, '#333');
    }
    
    function dump()
    {
        echo $this->print_r($this);
        return;
    }
}


$Test = &new AnalyticsTestCase();
$Test->run(new HtmlReporter());

$Test->echo_d('test complete in '.$Test->get_script_time().' s', '#600');
?>
